﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using PlanningGIS.DataCheck;
using PlanningGIS.Framework.Rule;
using PlanningGIS.Util.Collections;

namespace PlanningGIS.DataCheck
{
    /// <summary>
    /// 
    /// </summary>
    public class DataCheck
    {
        /// <summary>
        /// 数据检查规则
        /// </summary>
        [XmlArrayAttribute("DataCheckRules")]
        public List<DataCheckRule> DataCheckRules { get; set; }

    }


    #region 数据检查相关规则

    /// <summary>
    /// 数据检查规则
    /// </summary>
    [Serializable]
    public class DataCheckRule : RuleXml
    {
        /// <summary>
        /// 是否默认
        /// </summary>
        [XmlAttribute]
        public bool IsDefault;

        /// <summary>
        /// 数据入库规则名称
        /// </summary>
        [XmlAttribute]
        public string DataImportRuleName;

        /// <summary>
        /// 代码名称
        /// </summary>
        [XmlAttribute]
        public string FcodeName;

        /// <summary>
        /// 比例尺
        /// </summary>
        [XmlAttribute(DataType = "double")]
        public double Scale;

        /// <summary>
        /// 标记类型
        /// </summary>
        [XmlAttribute]
        public string MarkType;

        /// <summary>
        /// Topo检查规则
        /// </summary>
        [XmlArrayAttribute("TopoCheckRules")]
        public List<TopoCheckRule> TopoCheckRules;

        /// <summary>
        /// 注记检查规则
        /// </summary>
        [XmlArrayAttribute("AnnoCheckRules")]
        public List<AnnoCheckRule> AnnoCheckRules;

        /// <summary>
        /// 属性检查规则
        /// </summary>
        [XmlArrayAttribute("AttrCheckRules")]
        public List<AttrCheckRule> AttrCheckRules;

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return base.RuleName;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public DataCheckRule()
        {
            IsDefault = true;
            //DataType = "基础数据";
            Scale = 50;
            MarkType = "Shape";
        }
    }

    #region 检查需要的枚举类型
    /// <summary>
    /// 空间范围枚举：0为按全图查；1为按可视范围查；2为按图幅查
    /// </summary>
    public enum EnumSpatialFilter
    {
        /// <summary>
        /// 为按全图查
        /// </summary>
        CheckByLayer = 0,

        /// <summary>
        /// 为按可视范围查
        /// </summary>
        CheckByActiveExtent = 1,

        /// <summary>
        /// 为按图幅查
        /// </summary>
        CheckByMapsheet = 2,

        /// <summary>
        /// 未设置
        /// </summary>
        NotSet = 999
    }

    /// <summary>
    /// 属性条件枚举：0为按全要素查；1为按分类代码查
    /// </summary>
    public enum EnumAttrFilter
    {
        /// <summary>
        /// 为按全要素查
        /// </summary>
        CheckByFull = 0,

        /// <summary>
        /// 为按分类代码查
        /// </summary>
        CheckByFCODE = 1,

        /// <summary>
        /// 未设置
        /// </summary>
        NotSet = 999
    }
    #endregion

    /// <summary>
    /// 属性过滤条件
    /// </summary>
    [Serializable]
    public class AttrFilterDC
    {
        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute("EnumAttrFilter")]
        public int AttrFilter;

        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public bool P2P;

        /// <summary>
        /// 
        /// </summary>
        [XmlElement]
        public SQL SQL;

        /// <summary>
        /// 
        /// </summary>
        [XmlElement]
        public SQL SQL2;

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public string GetSQL()
        {
            EnumAttrFilter enumAttrFilter = (EnumAttrFilter)AttrFilter;
            switch (enumAttrFilter)
            {
                case EnumAttrFilter.CheckByFCODE:
                    if (SQL == null || SQL.FeatureCodes == null || SQL.FeatureCodes.Count == 0)
                    {
                        throw new Exception("该规则是按分类代码检查，但是分类代码列表为空，请核查！");
                    }
                    return SQL.ToString();
                case EnumAttrFilter.CheckByFull:
                    return "";
                default:
                    throw new Exception("尚未制定属性过滤条件！");

            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public string GetSQL2()
        {
            EnumAttrFilter enumAttrFilter = (EnumAttrFilter)AttrFilter;
            switch (enumAttrFilter)
            {
                case EnumAttrFilter.CheckByFCODE:
                    if (SQL2 == null || SQL2.FeatureCodes == null || SQL2.FeatureCodes.Count == 0)
                    {
                        throw new Exception("该规则是按分类代码检查，但是分类代码列表为空，请核查！");
                    }
                    return SQL2.ToString();
                case EnumAttrFilter.CheckByFull:
                    return "";
                default:
                    throw new Exception("尚未制定属性过滤条件！");

            }
        }
    }

    /// <summary>
    /// 要素类别名以及分类代码列表
    /// </summary>
    [Serializable]
    public class SQL
    {
        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string FeatClsAliasName;

        /// <summary>
        /// 
        /// </summary>
        [XmlArrayAttribute("Filter")]
        public List<FeatureCode> FeatureCodes;

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            if (FeatureCodes == null || FeatureCodes.Count == 0) return "";
            string fcodeName;
            fcodeName = ListHelper.GetEnumeratorItem(DataCheckHelper.DataCheck.DataCheckRules, "IsDefault", true).FcodeName;

            string rst;
            rst = fcodeName + " in ('";
            foreach (FeatureCode featureCode in FeatureCodes)
            {
                rst = rst + featureCode.FCODE + "','";
            }
            rst = rst.Substring(0, rst.Length - 2) + ")";
            return rst;
        }
    }


    /// <summary>
    /// 字段过滤条件
    /// </summary>
    [Serializable]
    public class FieldFilterDC
    {
        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string FeatClsAliasName;

        /// <summary>
        /// 
        /// </summary>
        [XmlArrayAttribute("Filter")]
        public List<Field> Fields;

    }

    /// <summary>
    /// 辅助层条件（针对要素查注记检查）
    /// </summary>
    [Serializable]
    public class FeatClsAss
    {
        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string FeatLyrName;

        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string FeatClsAliasName;

        /// <summary>
        /// 
        /// </summary>
        [XmlArrayAttribute("Filter")]
        public List<Fcode2Fcode> F2Fs;
    }

    /// <summary>
    /// 要素类别名以及文本与分类代码对应关系
    /// </summary>
    [Serializable]
    public class MatchInfo
    {
        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string FeatClsAliasName;

        /// <summary>
        /// 
        /// </summary>
        [XmlArrayAttribute("Filter")]
        public List<Fcode2Text> F2Ts;
    }

    /// <summary>
    /// 分类代码与文本的对应关系
    /// </summary>
    [Serializable]
    public class Fcode2Text
    {
        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string Text;

        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string FCODE;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool IsIn(string value)
        {
            if (Text == null | Text == "") return false;
            if (Text.IndexOf('%') == -1)
            {
                return (Text == value) ? true : false;
            }
            else
            {
                string[] rst = Text.Split('%');

                foreach (string item in rst)
                {
                    if (item != "") if (value.Contains(item)) return true;
                }
                return false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public string SQL()
        {
            if (Text == null | Text == "") return "";
            if (Text.IndexOf('%') == -1)
            {
                return "TextString = '" + Text + "'";
            }
            else
            {
                return "TextString like '" + Text + "'";
            }
        }
    }

    /// <summary>
    /// 拓扑检查规则
    /// </summary>
    [Serializable]
    public class TopoCheckRule : BaseCheckRule
    {
        /// <summary>
        /// 
        /// </summary>
        [XmlElement("AttrFilter")]
        public AttrFilterDC AttrFilter;


    }

    /// <summary>
    /// 注记检查规则
    /// </summary>
    [Serializable]
    public class AnnoCheckRule : BaseCheckRule
    {
        /// <summary>
        /// 
        /// </summary>
        public AnnoCheckRule()
        {
            SpatialRelEnum = 0; //将空间关系枚举初始化为0(esriSpatialRelUndefined)，因为XML数字型属性不能为空！
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public int SpatialRelEnum;

        /// <summary>
        /// 
        /// </summary>
        [XmlElement("AttrFilter")]
        public AttrFilterDC AttrFilter;

        /// <summary>
        /// 
        /// </summary>
        [XmlElement("FieldFilter")]
        public FieldFilterDC FieldFilter;

        /// <summary>
        /// 
        /// </summary>
        [XmlElement]
        public FeatClsAss FeatClsAss;

        /// <summary>
        /// 
        /// </summary>
        [XmlElement]
        public MatchInfo MatchInfo;
    }

    /// <summary>
    /// 属性检查规则
    /// </summary>
    [Serializable]
    public class AttrCheckRule : BaseCheckRule
    {
        /// <summary>
        /// 
        /// </summary>
        public AttrCheckRule()
        {
            SpatialRelEnum = 0;
        }

        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public int SpatialRelEnum;

        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string FeatClsAliasName;

        /// <summary>
        /// 
        /// </summary>
        [XmlElement]
        public RelateInfo RelateInfo;

        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string FieldName;

        /// <summary>
        /// 
        /// </summary>
        [XmlAttribute]
        public string Tag;

    }
    #endregion

}
